package com.jay.net.clazz.socket.udp;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPClient {
	public static final int MAX_DATAGRAM_BYTES = 512;
	public static final int MAX_SEND_QUEUE = 4;
	public static final int MAX_RECV_QUEUE = 4;
	public static final int MAX_RETRIES = 4;
	public static final int TIMEOUT = 2 * 1000;
	DatagramSocket socket;
	DatagramPacket packet;

	public UDPClient(InetAddress address, int port) throws IOException {
		this.socket = new DatagramSocket();// system-chosen port
		this.packet = new DatagramPacket(null, 0, address, port);
		socket.setSendBufferSize(MAX_DATAGRAM_BYTES * MAX_SEND_QUEUE);
		socket.setReceiveBufferSize(MAX_DATAGRAM_BYTES * MAX_RECV_QUEUE);
	}

	// Retry as necessary at increasing intervals:
	// throw InterruptedIOException if no reply
	public int sendReceive(byte[] buffer, int offset, int length)
			throws IOException {
		packet.setData(buffer, offset, length);
		IOException exception = null;
		int timeout = TIMEOUT;
		for (int i = 0; i < MAX_RETRIES; i++) {
			socket.send(packet);
			try {
				socket.setSoTimeout(timeout);
				socket.receive(packet);
				return packet.getLength();// return actual length
			}
			// catch InterruptedIOException rather than
			// SocketTimeoutException, so as to support all JDKs
			catch (InterruptedIOException iioexc) {
				exception = iioexc;
				timeout *= 2; // exponential backoff
			}
		}
		throw exception;
	} // sendReceive()
} // class
